﻿using System;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using DevComponents.DotNetBar.Controls;
using DevComponents.DotNetBar;
using DevComponents.AdvTree;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.DataSourcesGDB;
using PlanningGIS.Win.Controls;
using PlanningGIS.ArcGIS;
using PlanningGIS.ArcGIS.Custom;
using ESRI.ArcGIS.DataSourcesOleDB;
using ESRI.ArcGIS.DataSourcesRaster;
using PlanningGIS.Util.Log;

namespace PlanningGIS.Engine.Controls
{
    /// <summary>
    /// 作用：文件列表控件,基于ListViewEx扩展
    /// </summary>
    public partial class FileList : ListViewEx
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public FileList()
        {
            InitializeComponent();
            history = new PathHistoty();
            SmallImageList = ImageUtility.GetImageList();
            LargeImageList = ImageUtility.GetImageList();
            this.View = View.List;
        }
        /// <summary>
        /// 打开的SDE
        /// </summary>
        private List<string> sdeOpened = null;
        /// <summary>
        /// 历史路径
        /// </summary>
        private PathHistoty history;
        /// <summary>
        /// 双击文件或entry键选择文件
        /// </summary>
        public event DataFinished FileDoubleClick = null;
        /// <summary>
        /// 双击目录或entry键选择目录
        /// </summary>
        public event DataFinished PathDoubleClick = null;
        /// <summary>
        /// 选择文件
        /// </summary>
        public event DataFinished FileSelected = null;

        /// <summary>
        /// 获取选择对象指定节点类型的数据
        /// </summary>
        /// <typeparam name="T">如LayerNode</typeparam>
        /// <returns></returns>
        public List<T> GetSelectNode<T>()
        {
            List<T> nodes = new List<T>();
            if (SelectedItems.Count != 0)
            {
                foreach (ListViewItem item in SelectedItems)
                {
                    if (item.Tag is T)
                    {
                        nodes.Add((T)item.Tag);
                    }
                }
                return nodes;
            }
            return nodes;
        }
        
        /// <summary>
        /// 获取所有的节点
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public List<T> GetAllNodes<T>()
        {
            List<T> nodes = new List<T>();
            if (Items.Count != 0)
            {
                foreach (ListViewItem item in Items)
                {
                    if (item.Tag is T)
                    {
                        nodes.Add((T)item.Tag);
                    }
                }
                return nodes;
            }
            return nodes;
        }

        /// <summary>
        /// 设置当前路径
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="changetype"></param>
        public void SetCurrentDir(object tag, zjgisChangeType changetype = zjgisChangeType.Dir)
        {
            try
            {
                history.AddHistory(tag);
                ChangeDir(tag, changetype);
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorText(ex);
            }
        }
        
        /// <summary>
        /// 改变当前的路径
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="changetype"></param>
        private void ChangeDir(object tag, zjgisChangeType changetype = zjgisChangeType.File)
        {
            if (PathDoubleClick != null && changetype == zjgisChangeType.File)
            {
                if (tag is IDataNode)
                {
                    PathDoubleClick(this, new DataEventArgs() { Data = (tag as IDataNode).Path });
                }
                else if (tag is string)
                {
                    PathDoubleClick(this, new DataEventArgs() { Data = (tag as string) });
                }
            }
            Items.Clear();
            if (tag is string)
            {
                AddItem(tag as string);
            }
            else if (tag is IDataNode)
            {
                AddDataNode(tag as IDataNode);
            }
            else
            {
                return;
            }
        }

        /// <summary>
        /// 判断路径是否为空间数据库
        /// </summary>
        /// <param name="factory"></param>
        /// <param name="type"></param>
        /// <param name="path"></param>
        /// <param name="fullpath"></param>
        /// <param name="datasetname"></param>
        /// <returns></returns>
        private bool IsGeoDatabase(IWorkspaceFactory factory, string type, string path, out string fullpath, out string datasetname)
        {
            datasetname = "";
            fullpath = path;
            if (path.ToLower().EndsWith(type))
            {
                if (factory.IsWorkspace(path)) return true;
                return false;
            }
            int index = path.LastIndexOf("\\");
            fullpath = path.Substring(0, index);
            datasetname = path.Substring(index + 1);
            if (fullpath.ToLower().EndsWith(type))
            {
                if (factory.IsWorkspace(fullpath)) return true;
                return false;
            }
            return false;
        }

        /// <summary>
        /// 添加目录中的子项到列表中
        /// </summary>
        /// <param name="path">目录</param>
        private void AddItem(string path)
        {
            path = path.Trim().Replace("/", "\\");
            string tmpPath = path;
            string name = "";
            int index = path.LastIndexOf("\\");
            if (index != -1)
            {
                tmpPath = path.Substring(0, index);
                name = path.Substring(index + 1);
            }
            if (File.Exists(path) || File.Exists(tmpPath)) //为文件且存在，mdb、sde、xls、dwg等
            {
                if (new AccessWorkspaceFactory().IsWorkspace(path))//mdb
                {
                    AddDataNode(new DataBaseNode() { Path = path, Name = name, WorkspaceType = zjgisWorkspaceType.mdb });
                }
                else if (new AccessWorkspaceFactory().IsWorkspace(tmpPath))//mdb
                {
                    AddDataNode(new DatasetNode() { Path = tmpPath, Name = name, WorkspaceType = zjgisWorkspaceType.mdb });
                }
                else if (new SdeWorkspaceFactory().IsWorkspace(path))
                {
                    AddDataNode(new DataBaseNode() { Path = path, Name = name, WorkspaceType = zjgisWorkspaceType.sde });
                }
                else if (new SdeWorkspaceFactory().IsWorkspace(tmpPath))
                {
                    AddDataNode(new DatasetNode() { Path = tmpPath, Name = name, WorkspaceType = zjgisWorkspaceType.sde });
                }
                else if (new ExcelWorkspaceFactory().IsWorkspace(path))
                {
                    AddDataNode(new DataBaseNode() { Path = path, Name = name, WorkspaceType = zjgisWorkspaceType.xls });
                }
                else if (new CadWorkspaceFactory().IsWorkspace(tmpPath))
                {
                    AddCad(new DataBaseNode() { Path = path, Name = name, WorkspaceType = zjgisWorkspaceType.cad });
                }
            }
            else if (new FileGDBWorkspaceFactory().IsWorkspace(path))
            {
                AddDataNode(new DataBaseNode() { Path = path, Name = name, WorkspaceType = zjgisWorkspaceType.gdb });
            }
            else if (new FileGDBWorkspaceFactory().IsWorkspace(tmpPath))
            {
                AddDataNode(new DatasetNode() { Path = tmpPath, Name = name, WorkspaceType = zjgisWorkspaceType.gdb });
            }
            else
            {
                if (Directory.Exists(path))
                {
                    AddDir(path);
                    AddShp(path);
                    AddCAD(path);
                    AddRaster(path);
                    string[] files = Directory.GetFiles(path);
                    if (files == null || files.Length == 0) return;
                    foreach (string file in files)
                    {
                        FileInfo fi = new FileInfo(file);
                        if ("log".Equals(fi.Name, StringComparison.CurrentCultureIgnoreCase)) continue;
                        AddSde(fi);
                        AddMdb(fi);
                        AddLayer(fi);
                        AddExcel(fi);
                    }
                }
            }
        }

        /// <summary>
        /// 添加数据节点
        /// </summary>
        /// <param name="node"></param>
        private void AddDataNode(IDataNode node)
        {
            if (node is DataBaseNode)
            {
                IWorkspace workspace = node.Open() as IWorkspace;
                if (workspace != null)
                {
                    if (node.WorkspaceType == zjgisWorkspaceType.xls)
                        AddTable(node);
                    else
                    {
                        AddDataset(node);
                        AddFeatureClass(node);
                        AddRasterCatalog(node);
                        AddRasterDataset(node);
                    }
                }
            }
            else if (node is DatasetNode)
            {
                if (node.WorkspaceType == zjgisWorkspaceType.gdb ||
                    node.WorkspaceType == zjgisWorkspaceType.sde ||
                    node.WorkspaceType == zjgisWorkspaceType.mdb)
                {
                    AddFeatureClassOfDataset(node);
                }
                else if (node.WorkspaceType == zjgisWorkspaceType.cad)
                {
                    AddCad(node);
                }
                else if (node.WorkspaceType == zjgisWorkspaceType.xls)
                {
                    AddTable(node);
                }
            }
            else if (node is RasterCatalogNode)
            {
                AddRasterCatalog(node);
            }
        }

        #region 添加文件

        /// <summary>
        /// 添加目录到列表中
        /// </summary>
        /// <param name="path">要定位的的目录路径</param>
        private void AddDir(string path)
        {
            string[] dirs = Directory.GetDirectories(path);
            if (dirs == null || dirs.Length == 0) return;
            foreach (string dir in dirs)
            {
                DirectoryInfo di = new DirectoryInfo(dir);
                if ("info".Equals(di.Name, StringComparison.CurrentCultureIgnoreCase)) continue;
                //切片缓存
                if (di.Name.Equals("Layers", StringComparison.CurrentCultureIgnoreCase) && (Directory.Exists(dir + "\\_alllayers"))) continue;                
                string imagekey = ImageUtility.folderclosed;
                object tag = dir;
                if ((new FileGDBWorkspaceFactory()).IsWorkspace(dir))
                {
                    imagekey = ImageUtility.gdb;
                    DataBaseNode dsNode = new DataBaseNode();
                    dsNode.Path = dir;
                    dsNode.WorkspaceType = zjgisWorkspaceType.gdb;
                    dsNode.Name = di.Name;
                    tag = dsNode;
                }
                else if (GeodatabaseHelper.IsGRID(dir))
                {
                    imagekey = ImageUtility.image;
                    RasterDatasetNode rdNode = new RasterDatasetNode();
                    rdNode.Path = dir;
                    rdNode.WorkspaceType = zjgisWorkspaceType.raster;
                    rdNode.Name = di.Name;
                    tag = rdNode;
                }
                ListViewItem item = Items.Add(dir.ToLower(), di.Name, imagekey);
                item.Tag = tag;
            }
        }

        /// <summary>
        /// 添加.sde文件
        /// </summary>
        /// <param name="fi"></param>
        private void AddSde(FileInfo fi)
        {
            if (!fi.Extension.Equals(PostFix.SDE, StringComparison.CurrentCultureIgnoreCase)) return;
            if (sdeOpened == null)
                sdeOpened = new List<string>();
            string s = sdeOpened.FirstOrDefault(t => t.Equals(fi.FullName, StringComparison.CurrentCultureIgnoreCase));
            string imageKey = "";
            if (string.IsNullOrEmpty(s) || string.IsNullOrWhiteSpace(s))
                imageKey = ImageUtility.sdediscon;
            else
                imageKey = ImageUtility.sdediscon;
            DataBaseNode nd = new DataBaseNode();
            nd.Path = fi.FullName;
            nd.WorkspaceType = zjgisWorkspaceType.sde;
            nd.Name = fi.Name;
            ListViewItem item = Items.Add(nd.Path.ToLower(), nd.Name, imageKey);
            item.Tag = nd;
        }

        /// <summary>
        /// 添加Shp文件
        /// </summary>
        /// <param name="path"></param>
        private void AddShp(string path)
        {
            IWorkspaceFactory wksFac = new ShapefileWorkspaceFactory();
            if (!wksFac.IsWorkspace(path)) return;
            IWorkspace wks = wksFac.OpenFromFile(path, 0);
            IEnumDatasetName enumName = wks.get_DatasetNames(esriDatasetType.esriDTAny);
            IDatasetName dsname = null;
            while ((dsname=enumName.Next()) != null)
            {
                if (dsname is IFeatureClassName)
                {
                    IFeatureClassName featname = dsname as IFeatureClassName;
                    string imageKey = GetImageKeysByFeatureClass(featname.FeatureType, featname.ShapeType, true);
                    FeatureClassNode nd = new FeatureClassNode();
                    nd.WorkspaceType = zjgisWorkspaceType.shp;
                    nd.Path = path + "\\" + dsname.Name + ".shp";
                    nd.Name = dsname.Name + ".shp";
                    ListViewItem item = Items.Add(nd.Path.ToLower(), nd.Name, imageKey);
                    item.Tag = nd;
                }
                
            }
            
        }

        /// <summary>
        /// 添加栅格文件
        /// </summary>
        /// <param name="path"></param>
        private void AddRaster(string path)
        {
            IWorkspaceFactory wksFac = new RasterWorkspaceFactory();
            if (!wksFac.IsWorkspace(path)) return;
            IWorkspace wks = wksFac.OpenFromFile(path, 0);
            IEnumDatasetName enumName = wks.get_DatasetNames(esriDatasetType.esriDTAny);
            IDatasetName dsname = null;
            while ((dsname = enumName.Next()) != null)
            {
                string p = path + "\\" + dsname.Name;
                //栅格数据若是文件目录，则表示是Grid格式，Grid在AddDir中已经添加了
                //Layers是切片
                if (Directory.Exists(p) && (!"Layers".Equals(dsname.Name, StringComparison.CurrentCultureIgnoreCase))) continue;
                RasterDatasetNode nd = new RasterDatasetNode();
                nd.WorkspaceType = zjgisWorkspaceType.raster;
                nd.Path = path + "\\" + dsname.Name;                
                nd.Name = dsname.Name;
                ListViewItem item = Items.Add(nd.Path.ToLower(), nd.Name, ImageUtility.image);
                item.Tag = nd;
            }

        }
        
        /// <summary>
        /// 添加CAD文件
        /// </summary>
        /// <param name="path"></param>
        private void AddCAD(string path)
        {
            IWorkspaceFactory wksFac = new CadWorkspaceFactory();
            if (!wksFac.IsWorkspace(path)) return;
            IWorkspace wks = wksFac.OpenFromFile(path, 0);
            IEnumDatasetName enumName = wks.get_DatasetNames(esriDatasetType.esriDTAny);
            IDatasetName dsname = null;
            while ((dsname = enumName.Next()) != null)
            {
                DatasetNode nd = new DatasetNode();
                nd.WorkspaceType = zjgisWorkspaceType.cad;
                nd.Path = path + "\\" + dsname.Name;
                nd.Name = dsname.Name;
                string img = ImageUtility.dgn;
                if(dsname.Name.ToLower().Trim().EndsWith(".dwg"))
                    img = ImageUtility.dwg;
                ListViewItem item = Items.Add(nd.Path.ToLower(), nd.Name, img);
                item.Tag = nd;
            }

        }

        /// <summary>
        /// 添加Mdb文件
        /// </summary>
        /// <param name="fi"></param>
        private void AddMdb(FileInfo fi)
        {
            if (!fi.Extension.Equals(PostFix.MDB, StringComparison.CurrentCultureIgnoreCase)) return;
            DataBaseNode nd = new DataBaseNode();           
            nd.WorkspaceType = zjgisWorkspaceType.mdb;
            nd.Path = fi.FullName;
            nd.Name = fi.Name;
            ListViewItem item = Items.Add(nd.Path.ToLower(), nd.Name, ImageUtility.mdb);
            item.Tag = nd;
        }

        /// <summary>
        /// 添加Excel文件到列表节点中
        /// </summary>
        /// <param name="fi"></param>
        private void AddExcel(FileInfo fi)
        {
            if (!PostFix.XLS.ToLower().Contains(fi.Extension.ToLower())) return;
            DataBaseNode nd = new DataBaseNode();
            nd.WorkspaceType = zjgisWorkspaceType.xls;
            nd.Path = fi.FullName;           
            nd.Name = fi.Name;
            ListViewItem item = Items.Add(nd.Path.ToLower(), nd.Name, ImageUtility.tableset);
            item.Tag = nd;
        }

        /// <summary>
        /// 添加lyr图层
        /// </summary>
        /// <param name="fi"></param>
        private void AddLayer(FileInfo fi)
        {
            if (!fi.Extension.Equals(PostFix.LYE)) return;
            LayerNode nd = new LayerNode();
            nd.WorkspaceType = zjgisWorkspaceType.lyr;
            nd.Path = fi.FullName;
            nd.Name = fi.Name;
            ListViewItem item = Items.Add(nd.Path.ToLower(), nd.Name, ImageUtility.layer);
            item.Tag = nd;
        }

        #endregion

        #region 添加数据库中的内容
        /// <summary>
        /// 添加数据集
        /// </summary>
        /// <param name="node"></param>
        private void AddDataset(IDataNode node)
        {
            IWorkspace workspace = node.Open() as IWorkspace;
            IEnumDatasetName pEnumDatasetName = workspace.get_DatasetNames(esriDatasetType.esriDTFeatureDataset);
            IDatasetName pDatasetName = pEnumDatasetName.Next();
            while (pDatasetName != null)
            {
                DatasetNode dsnode = new DatasetNode();
                dsnode.Name = pDatasetName.Name;                
                dsnode.WorkspaceType = node.WorkspaceType;
                string key = node.Path + "\\" + pDatasetName.Name;
                dsnode.Path = key;
                dsnode.PropertySet = node.PropertySet;
                ListViewItem item = Items.Add(key.ToLower(), pDatasetName.Name, ImageUtility.dataset);
                item.Tag = dsnode;
                item.ImageKey = ImageUtility.dataset;
                pDatasetName = pEnumDatasetName.Next();
            }
        }

        /// <summary>
        /// 添加栅格数据
        /// </summary>
        /// <param name="node"></param>
        private void AddRasterCatalog(IDataNode node)
        {
            IWorkspace workspace = node.Open() as IWorkspace;
            IEnumDatasetName enumDatasetName = workspace.get_DatasetNames(esriDatasetType.esriDTRasterCatalog);
            IDatasetName datasetName = enumDatasetName.Next();
            while (datasetName != null)
            {
                RasterCatalogNode rcNode = new RasterCatalogNode();
                if (datasetName is IObjectClass)
                {
                    IObjectClass objClass = datasetName as IObjectClass;
                    rcNode.AliasName = objClass.AliasName;
                }
                string fullPath = node.Path + "\\" + datasetName.Name;
                rcNode.Path = fullPath;
                rcNode.PropertySet = node.PropertySet;
                rcNode.Name = datasetName.Name;
                rcNode.WorkspaceType = node.WorkspaceType;
                ListViewItem item = Items.Add(fullPath.ToLower(), datasetName.Name, ImageUtility.rastercatalog);
                item.Tag = rcNode;
                item.ImageKey = ImageUtility.rastercatalog;
                datasetName = enumDatasetName.Next();
            }
        }

        /// <summary>
        /// 添加栅格数据集
        /// </summary>
        /// <param name="node"></param>
        private void AddRasterDataset(IDataNode node)
        {
            IWorkspace workspace = node.Open() as IWorkspace;
            IEnumDatasetName pEnumDatasetName = workspace.get_DatasetNames(esriDatasetType.esriDTRasterDataset);
            IDatasetName pDatasetName = pEnumDatasetName.Next();
            while (pDatasetName != null)
            {
                RasterDatasetNode rdNode = new RasterDatasetNode();                
                string fullPath = node.Path + "\\" + pDatasetName.Name;
                rdNode.Path = fullPath;
                rdNode.WorkspaceType = node.WorkspaceType;
                rdNode.PropertySet = node.PropertySet;
                rdNode.Name = pDatasetName.Name;
                ListViewItem item = Items.Add(fullPath.ToLower(), pDatasetName.Name, ImageUtility.rasterdataset);
                item.Tag = rdNode;
                pDatasetName = pEnumDatasetName.Next();
            }
        }

        /// <summary>
        /// 添加要素类
        /// </summary>
        /// <param name="node"></param>
        private void AddFeatureClass(IDataNode node)
        {
            IWorkspace workspace = node.Open() as IWorkspace;
            IEnumDatasetName enumDatasetName = workspace.get_DatasetNames(esriDatasetType.esriDTFeatureClass);
            IDatasetName datasetName = enumDatasetName.Next();
            while (datasetName != null)
            {
                FeatureClassNode fcNode = new FeatureClassNode();
                fcNode.WorkspaceType = node.WorkspaceType;
                string fullPath = node.Path + "\\" + datasetName.Name;

                fcNode.Path = fullPath;
                fcNode.PropertySet = node.PropertySet;
                fcNode.Name = datasetName.Name;

                IFeatureClassName pFeatClsName = datasetName as IFeatureClassName;
                string imgkey = GetImageKeysByFeatureClass(pFeatClsName.FeatureType, pFeatClsName.ShapeType, false);
                if (!string.IsNullOrEmpty(imgkey) && !string.IsNullOrWhiteSpace(imgkey))
                {
                    ListViewItem item = Items.Add(fullPath.ToLower(), datasetName.Name, imgkey);
                    item.Tag = fcNode;
                } 
                datasetName = enumDatasetName.Next();
            }
        }

        /// <summary>
        /// 获取数据节点中所有的要素节点
        /// </summary>
        /// <param name="node">数据节点</param>
        /// <param name="addtolist">是否添加到控件列表中</param>
        /// <returns></returns>
        private List<FeatureClassNode> GetFeatureClass(IDataNode node, bool addtolist = false)
        {
            List<FeatureClassNode> clsnodes = new List<FeatureClassNode>();
            if (node is FeatureClassName)
            {
                clsnodes.Add(node as FeatureClassNode);
                return clsnodes;
            }
            if (!(node is DataBaseNode) && !(node is DatasetNode)) return null;            
            IWorkspace workspace = node.Open() as IWorkspace;
            IEnumDatasetName enumDatasetName = workspace.get_DatasetNames(esriDatasetType.esriDTFeatureClass);
            IDatasetName datasetName = enumDatasetName.Next();
            while (datasetName != null)
            {
                FeatureClassNode fcNode = new FeatureClassNode();
                fcNode.WorkspaceType = node.WorkspaceType;
                string fullPath = node.Path + "\\" + datasetName.Name;

                fcNode.Path = fullPath;
                fcNode.PropertySet = node.PropertySet;
                fcNode.Name = datasetName.Name;

                clsnodes.Add(fcNode);
                if (addtolist)
                {
                    IFeatureClassName pFeatClsName = datasetName as IFeatureClassName;
                    string imgkey = GetImageKeysByFeatureClass(pFeatClsName.FeatureType, pFeatClsName.ShapeType, false);
                    if (!string.IsNullOrEmpty(imgkey) && !string.IsNullOrWhiteSpace(imgkey))
                    {
                        ListViewItem item = Items.Add(fullPath.ToLower(), datasetName.Name, imgkey);
                        item.Tag = fcNode;
                    }
                }                
                datasetName = enumDatasetName.Next();
            }
            return clsnodes;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        private void AddTable(IDataNode node)
        {
            try
            {
                IWorkspace workspace = node.Open() as IWorkspace;
                IEnumDatasetName enumNames = workspace.get_DatasetNames(esriDatasetType.esriDTTable);
                IDatasetName itmName = enumNames.Next();
                while (itmName != null)
                {
                    TableNode rdNode = new TableNode();
                    string fullPath = node.Path + "\\" + itmName.Name;
                    rdNode.Path = fullPath;
                    rdNode.WorkspaceType = node.WorkspaceType;
                    rdNode.PropertySet = node.PropertySet;
                    rdNode.Name = itmName.Name;
                    ListViewItem item = Items.Add(fullPath.ToLower(), itmName.Name, ImageUtility.rasterdataset);
                    item.Tag = rdNode;
                    itmName = enumNames.Next();
                }
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(ex.Message);
            }
            
        }

        /// <summary>
        /// 添加数据集中的要素类
        /// </summary>
        /// <param name="dsNode"></param>
        private void AddFeatureClassOfDataset(IDataNode dsNode)
        {
            IDataset dataset = dsNode.Open();
            if (dataset == null) return;
            //通过IEnumDatasetName来获取要素类的名称，更快
            IEnumDatasetName enumFeatureDatasetName = dataset.Workspace.get_DatasetNames(esriDatasetType.esriDTFeatureDataset);
            IDatasetName datasetName = enumFeatureDatasetName.Next();
            IFeatureDatasetName pFeatureDatasetName = null;
            while (datasetName != null)
            {
                if (datasetName.Name.ToUpper() == dataset.Name.ToUpper())
                {
                    pFeatureDatasetName = datasetName as IFeatureDatasetName;
                    break;
                }
                datasetName = enumFeatureDatasetName.Next();
            }
            if (pFeatureDatasetName == null) return;
            IDatasetContainerName datasetContainerName = pFeatureDatasetName as IDatasetContainerName;
            IEnumDatasetName enumDatasetName = datasetContainerName.get_DatasetNames(esriDatasetType.esriDTFeatureClass);
            datasetName = enumDatasetName.Next();
            while (datasetName != null)
            {
                FeatureClassNode fcNode = new FeatureClassNode();
                fcNode.WorkspaceType = dsNode.WorkspaceType;
                string fullPath = dsNode.Path + "\\" + datasetName.Name;
                fcNode.Path = fullPath;
                fcNode.PropertySet = dsNode.PropertySet;
                fcNode.Name = datasetName.Name;
                IFeatureClassName pFeatClsName = datasetName as IFeatureClassName;
                
                string imgkey = GetImageKeysByFeatureClass(pFeatClsName.FeatureType, pFeatClsName.ShapeType, false);
                if (!string.IsNullOrEmpty(imgkey) && !string.IsNullOrWhiteSpace(imgkey))
                {
                    ListViewItem item = Items.Add(fullPath.ToLower(), datasetName.Name, imgkey);
                    item.Tag = fcNode;
                } 
                datasetName = enumDatasetName.Next();
            }
        }

        /// <summary>
        /// 添加CAD文件
        /// </summary>
        /// <param name="dsNode"></param>
        private void AddCad(IDataNode dsNode)
        {
            string path = dsNode.Path.TrimEnd('\\');
            string workspacepath = path;
            int index = workspacepath.LastIndexOf('\\');
            workspacepath = workspacepath.Substring(0, index);
            if ((new CadWorkspaceFactory()).IsWorkspace(workspacepath))
            {
                string caddrawingdataset = dsNode.Name;
                string Point = dsNode.Name + ":Point";
                string Polyline = dsNode.Name + ":Polyline";
                string Polygon = dsNode.Name + ":Polygon";
                string MultiPatch = dsNode.Name + ":MultiPatch";
                string Annotation = dsNode.Name + ":Annotation";

                CadDrawingDatasetNode cadNode = new CadDrawingDatasetNode();
                cadNode.WorkspaceType = zjgisWorkspaceType.cad;
                cadNode.Path = path;
                cadNode.Name = caddrawingdataset;
                ListViewItem item = Items.Add(cadNode.Path.ToLower(), caddrawingdataset, ImageUtility.preview);
                item.Tag = cadNode;

                FeatureClassNode fcNode;

                fcNode = new FeatureClassNode();
                fcNode.WorkspaceType = zjgisWorkspaceType.cad;
                fcNode.Path = path + "\\" + Annotation;
                fcNode.Name = Annotation;
                item = Items.Add(fcNode.Path.ToLower(), Annotation, ImageUtility.anno);
                item.Tag = fcNode;

                fcNode = new FeatureClassNode();
                fcNode.WorkspaceType = zjgisWorkspaceType.cad;
                fcNode.Path = path + "\\" + Point;
                fcNode.Name = Point;
                item = Items.Add(fcNode.Path.ToLower(), Point, ImageUtility.point);
                item.Tag = fcNode;

                fcNode = new FeatureClassNode();
                fcNode.WorkspaceType = zjgisWorkspaceType.cad;
                fcNode.Path = path + "\\" + Polyline;
                fcNode.Name = Polyline;
                item = Items.Add(fcNode.Path.ToLower(), Polyline, ImageUtility.polyline);
                item.Tag = fcNode;

                fcNode = new FeatureClassNode();
                fcNode.WorkspaceType = zjgisWorkspaceType.cad;
                fcNode.Path = path + "\\" + Polygon;
                fcNode.Name = Polygon;
                item = Items.Add(fcNode.Path.ToLower(), Polygon, ImageUtility.polygon);
                item.Tag = fcNode;

                fcNode = new FeatureClassNode();
                fcNode.WorkspaceType = zjgisWorkspaceType.cad;
                fcNode.Path = path + "\\" + MultiPatch;
                fcNode.Name = MultiPatch;
                item = Items.Add(fcNode.Path.ToLower(), MultiPatch, ImageUtility.multipatch);
                item.Tag = fcNode;
            }
        }

        /// <summary>
        /// 获取要素类的图标
        /// </summary>
        /// <param name="feattype"></param>
        /// <param name="shapetype"></param>
        /// <param name="isShp"></param>
        /// <returns></returns>
        private string GetImageKeysByFeatureClass(esriFeatureType feattype, esriGeometryType shapetype, bool isShp)
        {
            if (feattype == esriFeatureType.esriFTAnnotation) return ImageUtility.anno;
            if (shapetype == esriGeometryType.esriGeometryPoint || shapetype == esriGeometryType.esriGeometryMultipoint)
                return isShp ? ImageUtility.point_shp : ImageUtility.point;
            else if (shapetype == esriGeometryType.esriGeometryPolyline || shapetype == esriGeometryType.esriGeometryLine)
                return isShp ? ImageUtility.polyline_shp : ImageUtility.polyline;
            else if (shapetype == esriGeometryType.esriGeometryPolygon)
                return isShp ? ImageUtility.polygon_shp : ImageUtility.polygon;
            else if (shapetype == esriGeometryType.esriGeometryMultiPatch)
                return isShp ? ImageUtility.multipatch_shp : ImageUtility.multipatch;
            return ImageUtility.point;
        }

        /// <summary>
        /// 添加栅格数据子项
        /// </summary>
        /// <param name="rcNode"></param>
        private void AddRasterCatalogItem(IDataNode rcNode)
        {
            string path = rcNode.Path.TrimEnd('\\');
            IDataset dataset = rcNode.Open();
            if (dataset == null) return;
            IRasterCatalog pRasterCatalog = dataset as IRasterCatalog;
            if (pRasterCatalog == null) return;
            IFeatureClass pFeatCls = pRasterCatalog as IFeatureClass;
            if (pFeatCls == null) return;
            IFeatureCursor pFeatCur = pFeatCls.Search(null, false);
            IFeature pFeature = null;
            while ((pFeature = pFeatCur.NextFeature()) != null)
            {
                IRasterCatalogItem pRasterCatalogItem = pFeature as IRasterCatalogItem;
                if (pRasterCatalogItem == null) continue;
                int idx = pFeature.Fields.FindField("Name");
                if (idx == -1) break;
                string name = pFeature.get_Value(idx).ToString();

                RasterDatasetNode rdNode = new RasterDatasetNode();
                rdNode.Path = rcNode.Path;
                rdNode.WorkspaceType = rcNode.WorkspaceType;
                rdNode.PropertySet = rcNode.PropertySet;
                rdNode.Name = dataset.Name + "\\Raster.OBJECTID =" + pFeature.OID.ToString();
                rdNode.Tag = pRasterCatalogItem.RasterDataset;

                string fullPath = path.TrimEnd('\\') + name;
                ListViewItem item = Items.Add(fullPath.ToLower(), name, ImageUtility.rasterdataset);
                item.Tag = rdNode;
            }
            Marshal.ReleaseComObject(pFeatCur);
        }
        #endregion

        /// <summary>
        /// 双击选择
        /// </summary>
        /// <param name="e"></param>
        protected override void OnItemActivate(EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            base.OnItemActivate(e);
            if (SelectedItems != null && SelectedItems.Count > 0)
            {
                ListViewItem item = SelectedItems[0];
                object tag = item.Tag;
                if (tag is FeatureClassNode || tag is RasterDatasetNode || tag is LayerNode || tag is TableNode)
                {
                    if (FileDoubleClick != null)
                    {
                        FileDoubleClick(this,new DataEventArgs() { Data = (tag as IDataNode) } );
                    }
                    this.Cursor = Cursors.Default;
                    return;
                }
                ChangeDir(tag);
            }
            this.Cursor = Cursors.Default;
        }

        /// <summary>
        /// 选择文件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            if (e.Button != System.Windows.Forms.MouseButtons.Left) return;
            string files = "";
            for (int i = 0; i < this.SelectedItems.Count; i++)
            {
                files += SelectedItems[i].Text + " | ";
            }
            if (!string.IsNullOrWhiteSpace(files.Trim()))
                files = files.Trim().Substring(0, files.Trim().Length - 1);
            if (FileSelected != null)
                FileSelected(this, new DataEventArgs() { Data = files });
        }

        /// <summary>
        /// 刷新名称
        /// </summary>
        /// <param name="alias"></param>
        public void RefreshName(bool alias)
        {
            if (this.Items.Count == 0) return;
            foreach (ListViewItem itm in this.Items)
            {
                if (itm.Tag == null) continue;
                if (itm.Tag is FeatureClassNode)
                {
                    IDataNode nd = itm.Tag as IDataNode;
                    if (alias)
                    {
                        if (string.IsNullOrWhiteSpace(nd.AliasName) || nd.AliasName.Equals(nd.Name, StringComparison.CurrentCultureIgnoreCase))
                        {
                            nd.Open();
                        }
                    }
                    itm.Text = alias ? nd.AliasName : nd.Name;
                }
            }
        }

        #region 上一步下一步操作类
        /// <summary>
        /// 后退
        /// </summary>
        public void Backward()
        {
            object tag = history.Back();
            if (tag is string || tag is DataBaseNode || tag is DatasetNode || tag is RasterCatalogNode)
                ChangeDir(tag);
        }
        /// <summary>
        /// 前进
        /// </summary>
        public void Forward()
        {
            object tag = history.Forward();
            if (tag is string || tag is DataBaseNode || tag is DatasetNode || tag is RasterCatalogNode)
                ChangeDir(tag);
        }
        /// <summary>
        /// 是否可以后退
        /// </summary>
        /// <returns></returns>
        public bool Canback()
        {
            return history.CanBack();
        }
        /// <summary>
        /// 是否可以前进
        /// </summary>
        /// <returns></returns>
        public bool CanForward()
        {
            return history.CanForward();
        }
        
        #endregion

    }


}
